/**
 * Created by Administrator on 2018/1/27.
 */
let gameData = require('../util/gameData.js');
let msg = require('../util/msg.js');
let mem = require('../util/mem.js');
let util = require('../util/util.js');
let rpc = require('../util/rpc.js');
let userDao = require('../mysql/userDao.js');
let log = require('../util/log.js');
let variable = require('../data/variable.js');

let method = module.exports;

method.matchStart = function (obj, cid, data) {
    console.log("method.matchStart>>>"); 
    if (mem.arenaPlayers[obj.userId]){
        msg.send(cid, obj.uuid, 'error', {'code': 10088});
        return false;
    }
    if (!gameData.d.gameLv[data.lv] || gameData.d.gameLv[data.lv].disable) {
        msg.send(cid, obj.uuid, 'error', {'code': 10027});
        return false;
    }
    method.user(obj.userId, cid, obj.uuid, function (res) {
        if (gameData.d.gameLv[data.lv].minCoin > 0 && res[gameData.d.gameLv[data.lv].coinType] < gameData.d.gameLv[data.lv].minCoin) {
            msg.send(cid, obj.uuid, 'error', {'code': 10029});
            return false;
        }
        if (gameData.d.gameLv[data.lv].maxCoin > 0 && res[gameData.d.gameLv[data.lv].coinType] > gameData.d.gameLv[data.lv].maxCoin) {
            msg.send(cid, obj.uuid, 'error', {'code': 10029});
            return false;
        }
        mem.matchPlayers[res.id] = {
            'cid': cid,
            'uuid': obj.uuid,
            'gameLv': data.lv,
            'user': res,
            'showCard': data.showCard,
            'lock': false
        };
        mem.matchPlayers[res.id].linkTime = Date.now();
        msg.send(cid, obj.uuid, 'matchStart');
    });
};
method.matchStop = function (obj, cid) {
    console.log("method.matchStop>>>"); 
    if (!mem.matchPlayers[obj.userId]) {
        return false;
    }
    delete mem.matchPlayers[obj.userId];
    msg.send(cid, obj.uuid, 'matchStop');
};
method.matchCustom = function (obj, cid, data) {
    console.log("method.matchCustom>>>"); 
    if (mem.arenaPlayers[obj.userId]){
        msg.send(cid, obj.uuid, 'error', {'code': 10088});
        return false;
    }
    method.user(obj.userId, cid, obj.uuid, function (res) {
        let param = util.userInfo(res);
        if( !param.card || param.card<1 ) {
            msg.send(cid, obj.uuid, 'error', {'code': 10089});
            return false;
        }   
        param.rounds = data.rounds;
        param.password = data.password; 
        
        rpc.game.send('customRoom', param, function (result) {
            if (result.code == 101) {
                msg.send(cid, obj.uuid, 'error', {'code': 10024});
                return false;
            }
            if (result.code == 102) {
                msg.send(cid, obj.uuid, 'matchInGame', {
                    'userId': obj.userId,
                    'gameId': result.gameId,
                    'local': result.local,
                    'gameType': result.gameType
                });
                return false;
            }
            if (result.code == 103) {
                msg.send(cid, obj.uuid, 'error', {'code': 10028});
                return false;
            }
            msg.send(cid, obj.uuid, 'matchCustom', {
                'userId': obj.userId,
                'gameId': result.key,
                'local': result.local,
                'qrCode': 'http://game.ku988.cn:' + variable.http.http + '/qrCode?fromUid=' + obj.userId + '&roomId=' + result.key
            });
        });
    });
};
method.matchFollow = function (obj, cid, data) {
    console.log("method.matchFollow>>>"); 
    if (mem.arenaPlayers[obj.userId]){
        msg.send(cid, obj.uuid, 'error', {'code': 10088});
        return false;
    }
    if (!data.gameId) {
        msg.send(cid, obj.uuid, 'error', {'code': 10030});
        return false;
    }
    method.user(obj.userId, cid, obj.uuid, function (res) {
        let param = util.userInfo(res);
        param.gameId = data.gameId;
        param.password = data.password;
        rpc.game.send('followRoom', param, function (result) {
            if (result.code == 101) {
                msg.send(cid, obj.uuid, 'error', {'code': 10024});
                return false;
            }   
            if (result.code == 102) {
                msg.send(cid, obj.uuid, 'matchInGame', {
                    'userId': obj.userId,
                    'gameId': result.gameId,
                    'local': result.local,
                    'gameType': result.gameType
                });
                return false;
            }
            if (result.code == 103) {
                msg.send(cid, obj.uuid, 'error', {'code': 10025});
                return false;
            }
            if (result.code == 104) {
                msg.send(cid, obj.uuid, 'error', {'code': 10026});
                return false;
            }
            if (result.code == 105) {
                msg.send(cid, obj.uuid, 'error', {'code': 10027});
                return false;
            }
            if (result.code == 106) {
                msg.send(cid, obj.uuid, 'error', {'code': 10028});
                return false;
            }
            msg.send(cid, obj.uuid, 'matchFollow', {
                'userId': obj.userId,
                'gameId': result.key,
                'local': result.local,
                'qrCode': 'http://game.ku988.cn:' + variable.http.http + '/qrCode?fromUid=' + obj.userId + '&roomId=' + result.key
            });
        });
    });
};
method.matchList = function (obj, cid) {
    method.user(obj.userId, cid, obj.uuid, function (res) {
        let param = util.userInfo(res);
        rpc.dc.send('getRecruit', param, function (data) {
            msg.send(cid, obj.uuid, 'matchList', data);
        });
    });
};
method.matchLineUp = function () {
    if (Object.keys(mem.matchPlayers).length <= 1) {
        return false;
    }
    // 用户分组，把不同等级的用户放到不同的组里
    let groups = {};
    let lvsNum = 0;
    for (let i in mem.matchPlayers) {
        if (!mem.matchPlayers[i] || mem.matchPlayers[i].lock == true) {
            continue;
        }
        // 以等级作为分组基准
        let lv = Math.floor(mem.matchPlayers[i].gameLv);
        if (!groups[lv]) {
            groups[lv] = [];
            lvsNum++;
        }
        groups[lv].push(i);
    }
    if (lvsNum < 1) {
        return false;
    }
    // 把不同组里的用户配给房间
    for (let i in groups) {
        // 如果组里不够3人则跳过
        if (groups[i].length < 3) {
            continue;
        }
        method.matchRoom(groups[i], i);
    }
};
// 检查排队超时
method.matchTimeOut = function () {
    if (Object.keys(mem.matchPlayers).length <= 0) {
        return false;
    }
    let timeoutRobot = gameData.d.config.timeoutRobot * 1000;
    let timeoutA = gameData.d.config.timeoutA * 1000;
    let timeoutB = gameData.d.config.timeoutB * 1000;
    let time = Date.now();
    for (let i in mem.matchPlayers) {
        if (!mem.matchPlayers[i]) {
            continue;
        }
        if (!mem.matchPlayers[i]) {
            continue;
        }
        if (!mem.matchPlayers[i].lock) {
            let c = time - mem.matchPlayers[i].linkTime;
            if (c > timeoutB) {
                msg.send(mem.matchPlayers[i].cid, mem.matchPlayers[i].uuid, 'matchEnd');
                delete mem.matchPlayers[i];
                continue;
            }   
            if (c > timeoutA) {
                msg.send(mem.matchPlayers[i].cid, mem.matchPlayers[i].uuid, 'matchOut');
                continue;
            }   
            if (c > timeoutRobot && gameData.d.config.robotTurnOn) {
                method.robotRoom(i);
            }
        }
    }
};
method.matchRoom = function (group, i) {
    //从组里取出3个人
    let selected = util.getRandItemsInArray(group, 3);
    // 整理取出的3个人的资料发给房间服务器
    let userList = [];
    for (let j in selected) {
        if (!mem.matchPlayers[selected[j]]) {
            continue;
        }
        mem.matchPlayers[selected[j]].lock = true;
        userList.push(selected[j]);
    }
    let data = {};
    data.user = [];
    data.lv = i;
    for (let j in userList) {
        let userInfo = util.userInfo(mem.matchPlayers[userList[j]].user);
        userInfo.uuid = mem.matchPlayers[userList[j]].uuid;
        userInfo.show = mem.matchPlayers[userList[j]].showCard;
        data.user.push(userInfo);
    }
    rpc.game.send(method.sendName(data.lv), data, function (result) {
        method.createRoomCB(result, userList);
    });
};
method.robotRoom = function (id) {
    let userList = [];
    mem.matchPlayers[id].lock = true;
    userList.push(id);
    let data = {};
    data.user = [];
    data.lv = mem.matchPlayers[id].gameLv;
    for (let j in userList) {
        let userInfo = util.userInfo(mem.matchPlayers[userList[j]].user);
        userInfo.uuid = mem.matchPlayers[userList[j]].uuid;
        data.user.push(userInfo);
    }
    let param = {};
    param.lv = data.lv;
    rpc.dc.send('getRobot', param, function (robotIds) {
        if (!robotIds) {
            setTimeout(function () {
                for (let j in userList) {
                    mem.matchPlayers[userList[j]].lock = false;
                }
            }, 5000);
            log.d('暂时没有机器人，5秒后再试');
            return false;
        }
        for (let j in robotIds) {
            let userInfo = util.userInfo(robotIds[j]);
            userInfo.robot = true;
            data.user.push(userInfo);
        }
        rpc.game.send(method.sendName(data.lv), data, function (result1) {
            method.createRoomCB(result1, userList);
        });
    });
};
method.createRoomCB = function (result, userList) {
    if (result.code == 404) {
        for (let j in userList) {
            mem.matchPlayers[userList[j]].lock = false;
        }
        log.d('房间服务器连接失败');
        return false;
    }
    if (result.code == 102) {
        let ids = [];
        for (let j in result.inGameId) {
            ids.push(j);
        }
        for (let j in userList) {
            if (ids.indexOf(userList[j]) >= 0) {
                msg.send(mem.matchPlayers[userList[j]].cid, mem.matchPlayers[userList[j]].uuid, 'matchInGame', {
                    'userId': userList[j],
                    'gameId': result.inGameId[userList[j]].gameId,
                    'local': result.inGameId[userList[j]].local,
                    'gameType': result.inGameId[userList[j]].gameType
                });
                delete mem.matchPlayers[userList[j]];
            } else {
                mem.matchPlayers[userList[j]].lock = false;
            }
        }
        return false;
    }
    if (result.code == 103) {
        let ids = [];
        for (let j in result.errId) {
            ids.push(j);
        }
        for (let j in userList) {
            if (ids.indexOf(userList[j]) >= 0) {
                msg.send(mem.matchPlayers[userList[j]].cid, mem.matchPlayers[userList[j]].uuid, 'error', {'code': 10028});
                delete mem.matchPlayers[userList[j]];
            } else {
                mem.matchPlayers[userList[j]].lock = false;
            }
        }
        return false;
    }
    if (result.code == 200) {
        let key = result.key;
        for (let j in userList) {
            let local = result.player[userList[j]];
            msg.send(mem.matchPlayers[userList[j]].cid, mem.matchPlayers[userList[j]].uuid, 'matchGame', {
                'userId': userList[j],
                'gameId': key,
                'local': local
            });
            delete mem.matchPlayers[userList[j]];
        }
        log.p('room:' + key + ',data:' + JSON.stringify(result));
    }
};

method.user = function (id, cid, uuid, cb) {
    let userModel = new userDao();
    userModel.inId(id, function (err, res) {
        if (res == null) {
            return false;
        }
        if (res.res.gameId && res.res.gameId != 0) {
            msg.send(cid, uuid, 'matchInGame', {
                'userId': res.res.id,
                'gameId': res.res.gameId
            });
            return false;
        }
        cb(res.res);
    });
};

method.sendName = function (lv) {
    switch (gameData.d.gameLv[lv].type) {
        case 'match':
            return 'createRoom';
        case 'happy':
            return 'happyRoom';
    }
};